package cn.huaqingcheng.tool.core;

import java.util.Objects;
import java.util.function.Supplier;

/**
 * 断言
 */
@SuppressWarnings("unused")
public interface Assert {

    /**
     * 断言 false
     *
     * @param shouldBeFalse 需要断言的条件
     * @param msg           错误消息模板 {@link String#formatted(Object...)}
     * @param args          错误消息参数
     */
    static void isFalse(boolean shouldBeFalse, String msg, Object... args) {
        if (shouldBeFalse) {
            throw new RuntimeException(Objects.requireNonNull(msg).formatted(args));
        }
    }

    /**
     * 断言 false
     *
     * @param shouldBeFalse 需要断言的条件
     * @param msg           错误消息提供
     */
    static void isFalse(boolean shouldBeFalse, Supplier<String> msg) {
        if (shouldBeFalse) {
            throw new RuntimeException(Objects.requireNonNull(msg).get());
        }
    }

    /**
     * 断言 false, 否则抛出自定义异常
     *
     * @param shouldBeFalse 需要断言的条件
     * @param e             自定义异常
     */
    static <E extends Throwable> void isFalseElseThrow(boolean shouldBeFalse, Supplier<E> e) throws E {
        if (shouldBeFalse) {
            throw Objects.requireNonNull(e).get();
        }
    }

    /**
     * 断言 true
     *
     * @param shouldBeTrue 需要断言的条件
     * @param msg          错误消息模板 {@link String#formatted(Object...)}
     * @param args         错误消息参数
     */
    static void isTrue(boolean shouldBeTrue, String msg, Object... args) {
        if (!shouldBeTrue) {
            throw new RuntimeException(Objects.requireNonNull(msg).formatted(args));
        }
    }

    /**
     * 断言为 true
     *
     * @param shouldBeTrue 需要断言的条件
     * @param msg          自定义错误消息
     */
    static void isTrue(boolean shouldBeTrue, Supplier<String> msg) {
        if (!shouldBeTrue) {
            throw new RuntimeException(Objects.requireNonNull(msg).get());
        }
    }

    /**
     * 断言为 true
     *
     * @param shouldBeTrue 需要断言的条件
     * @param e            自定义异常
     */
    static <E extends Throwable> void isTrueElseThrow(boolean shouldBeTrue, Supplier<E> e) throws E {
        if (!shouldBeTrue) {
            throw Objects.requireNonNull(e).get();
        }
    }

}
